package cn.schoolwow.quickdao.module.initial.flow.table;

import cn.schoolwow.quickdao.domain.QuickDAOConfig;
import cn.schoolwow.quickdao.domain.entity.Entity;
import cn.schoolwow.quickdao.domain.entity.Property;
import cn.schoolwow.quickdao.module.database.ddl.action.flow.column.DropTableColumnFlow;
import cn.schoolwow.quickdao.module.database.ddl.action.flow.table.DropTableFlow;
import cn.schoolwow.quickdao.module.database.ddl.common.flow.DeleteDatabaseEntityCacheFlow;
import cn.schoolwow.quickdao.module.database.ddl.query.flow.entity.GetEntityListFlow;
import cn.schoolwow.quickdao.module.database.ddl.query.flow.index.GetEntityIndexListFlow;
import cn.schoolwow.quickdao.module.database.ddl.query.flow.property.GetEntityPropertyListFlow;
import cn.schoolwow.quickflow.domain.FlowContext;
import cn.schoolwow.quickflow.flow.BusinessFlow;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class AutomaticDeleteTableAndPropertyFlow implements BusinessFlow {
    @Override
    public void executeBusinessFlow(FlowContext flowContext) throws Exception {
        QuickDAOConfig quickDAOConfig = flowContext.checkInstanceData(QuickDAOConfig.class);
        if(!quickDAOConfig.databaseOption.automaticDeleteTableAndProperty){
            flowContext.remark("跳过自动删除多余表和属性");
            return;
        }

        Map<String, Entity> entityMap = quickDAOConfig.databaseContext.entityMap;
        if (null == entityMap || entityMap.isEmpty()) {
            flowContext.remark("未扫描到任何实体类!请设置包路径或者实体类!");
            return;
        }
        List<Entity> databaseEntityList = (List<Entity>) flowContext.getQuickFlow().executeFlow(
                new GetEntityListFlow(),
                new GetEntityPropertyListFlow(),
                new GetEntityIndexListFlow()
        ).checkData("entityList");

        //待删除的表
        List<String> dropTableNameList = new ArrayList<>();
        //待删除的字段
        Map<String,List<String>> dropPropertyMap = new HashMap<>();
        for (Entity databaseEntity : databaseEntityList) {
            Entity sourceEntity = null;
            for(Entity _sourceEntity:entityMap.values()){
                if(_sourceEntity.tableName.equalsIgnoreCase(databaseEntity.tableName)){
                    sourceEntity = _sourceEntity;
                    break;
                }
            }
            if(null==sourceEntity){
                dropTableNameList.add(databaseEntity.tableName);
                continue;
            }

            for (Property dbProperty : databaseEntity.properties) {
                boolean dbPropertyExists = false;
                for (Property propertyItem : sourceEntity.properties) {
                    if (dbProperty.column.equalsIgnoreCase(propertyItem.column)) {
                        dbPropertyExists = true;
                        break;
                    }
                }
                if (!dbPropertyExists) {
                    if(!dropPropertyMap.containsKey(databaseEntity.tableName)){
                        dropPropertyMap.put(databaseEntity.tableName, new ArrayList<>());
                    }
                    dropPropertyMap.get(databaseEntity.tableName).add(dbProperty.column);
                }
            }
        }
        for (String dropTableName : dropTableNameList) {
            flowContext.startFlow(new DropTableFlow())
                    .next(new DeleteDatabaseEntityCacheFlow())
                    .putTemporaryData("tableName", dropTableName)
                    .execute();
        }
        for(Map.Entry<String,List<String>> entry:dropPropertyMap.entrySet()){
            for(String column:entry.getValue()){
                flowContext.getQuickFlow().startFlow(new DropTableColumnFlow())
                        .putTemporaryData("tableName", entry.getKey())
                        .putTemporaryData("columnName", column)
                        .execute();
            }
            flowContext.startFlow(new DeleteDatabaseEntityCacheFlow())
                    .putTemporaryData("tableName", entry.getKey())
                    .execute();
        }
    }

    @Override
    public String name() {
        return "自动删除多余表和属性";
    }
}
